#include "EpilStatementInterpreter.h"
#include "EpilInterpreter.h"
#include "EpilAssignStatementInterpreter.h"
#include "EpilFunctionCallStatementInterpreter.h"
#include "EpilLocalVariableStatementInterpreter.h"
#include "EpilBlockStatementInterpreter.h"
#include "EpilIfStatementInterpreter.h"
#include "EpilWhileStatementInterpreter.h"
#include "EpilRepeatStatementInterpreter.h"
#include "EpilForNumberStatementInterpreter.h"
#include "EpilReturnStatementInterpreter.h"
#include "EpilFunctionStatementInterpreter.h"
#include "EpilLocalFunctionStatementInterpreter.h"


EpilStatementInterpreter::EpilStatementInterpreter( EpilInterpreter * interpreter )
: EpilInterpreterBase( interpreter )
, m_exitReason( ECER_Normal )
, m_exitLocation( EpilLexLocation::InvalidLocation )
{
}


void EpilStatementInterpreter::Run( const EpilStatementCodeBase * code )
{
	switch( code->GetType() )
	{
	case ECT_AssignStatement:
		{
			const EpilAssignStatementCode * statement = static_cast<const EpilAssignStatementCode *>( code );
			EpilAssignStatementInterpreter interpreter( this->GetInterpreter() );
			interpreter.Run( statement );
		}
		break;
	case ECT_BlockStatement:
		{
			const EpilBlockStatementCode * statement = static_cast<const EpilBlockStatementCode *>( code );
			EpilBlockStatementInterpreter interpreter( this->GetInterpreter() );
			interpreter.Run( statement );
			m_exitReason = interpreter.GetExitReason();
			m_exitLocation = interpreter.GetExitLocation();
		}
		break;
	case ECT_BreakStatement:
		{
			m_exitReason = ECER_Break;
			m_exitLocation = code->GetLocation();
		}
		break;
	case ECT_ContinueStatement:
		{
			m_exitReason = ECER_Continue;
			m_exitLocation = code->GetLocation();
		}
		break;
	case ECT_ForListStatement:
		{

		}
		break;
	case ECT_ForNumberStatement:
		{
			const EpilForNumberStatementCode * statement = static_cast<const EpilForNumberStatementCode *>( code );
			EpilForNumberStatementInterpreter interpreter( this->GetInterpreter() );
			interpreter.Run( statement );
			m_exitReason = interpreter.GetExitReason();
			m_exitLocation = interpreter.GetExitLocation();
		}
		break;
	case ECT_FunctionCallStatement:
		{
			const EpilFunctionCallStatementCode * statement = static_cast<const EpilFunctionCallStatementCode *>( code );
			EpilFunctionCallStatementInterpreter interpreter( this->GetInterpreter() );
			interpreter.Run( statement );
		}
		break;
	case ECT_FunctionStatement:
		{
			const EpilFunctionStatementCode * statement = static_cast<const EpilFunctionStatementCode *>( code );
			EpilFunctionStatementInterpreter interpreter( this->GetInterpreter() );
			interpreter.Run( statement );
		}
		break;
	case ECT_IfStatement:
		{
			const EpilIfStatementCode * statement = static_cast<const EpilIfStatementCode *>( code );
			EpilIfStatementInterpreter interpreter( this->GetInterpreter() );
			interpreter.Run( statement );
			m_exitReason = interpreter.GetExitReason();
			m_exitLocation = interpreter.GetExitLocation();
		}
		break;
	case ECT_LocalFunctionStatement:
		{
			const EpilLocalFunctionStatementCode * statement = static_cast<const EpilLocalFunctionStatementCode *>( code );
			EpilLocalFunctionStatementInterpreter interpreter( this->GetInterpreter() );
			interpreter.Run( statement );
		}
		break;
	case ECT_LocalVariableStatement:
		{
			const EpilLocalVariableStatementCode * statement = static_cast<const EpilLocalVariableStatementCode*>( code );
			EpilLocalVariableStatementInterpreter interpreter( this->GetInterpreter() );
			interpreter.Run( statement );
		}
		break;
	case ECT_RepeatStatement:
		{
			const EpilRepeatStatementCode * statement = static_cast<const EpilRepeatStatementCode *>( code );
			EpilRepeatStatementInterpreter interpreter( this->GetInterpreter() );
			interpreter.Run( statement );
			m_exitReason = interpreter.GetExitReason();
			m_exitLocation = interpreter.GetExitLocation();
		}
		break;
	case ECT_ReturnStatement:
		{
			const EpilReturnStatementCode * statement = static_cast<const EpilReturnStatementCode *>( code );
			EpilReturnStatementInterpreter interpreter( this->GetInterpreter() );
			interpreter.Run( statement );
			m_exitReason = interpreter.GetExitReason();
			m_exitLocation = interpreter.GetExitLocation();
		}
		break;
	case ECT_WhileStatement:
		{
			const EpilWhileStatementCode * statement = static_cast<const EpilWhileStatementCode *>( code );
			EpilWhileStatementInterpreter interpreter( this->GetInterpreter() );
			interpreter.Run( statement );
			m_exitReason = interpreter.GetExitReason();
			m_exitLocation = interpreter.GetExitLocation();
		}
		break;
	}
}